/*******************************************************************************
* 2019 - present Contributed by Apulis Technology (Shenzhen) Co. LTD
*
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available at
* https://www.opensource.org/licenses/MIT
*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: MIT
******************************************************************************/

package exports

import (
	"net/http"
)

const (
	SUCCESS = 0

	AILAB_ERROR_RUNNING = 280000023 // ailab some thing is running,need wait
)

const (
	APULIS_IQI_ERROR_BEGIN = APULIS_IQI_MODULE_ID*100000 + iota
	APULIS_IQI_NOT_FOUND
	APULIS_IQI_PARAM_ERROR
	APULIS_IQI_ALREADY_EXISTS
	APULIS_IQI_NO_API
	APULIS_IQI_NOT_IMPLEMENT
	APULIS_IQI_UNKNOWN_ERROR

	APULIS_IQI_FILE_NOT_FOUND
	APULIS_IQI_PATH_NOT_FOUND

	APULIS_IQI_OS_IO_ERROR
	APULIS_IQI_OS_READ_DIR_ERROR
	APULIS_IQI_OS_REMOVE_FILE
	APULIS_IQI_OS_CREATE_FILE
	APULIS_IQI_FILE_TOO_LARGE
	APULIS_IQI_FILE_TYPE_ERROR

	APULIS_IQI_COMPUTE_EXCEED_LIMIT
	APULIS_IQI_COMPUTE_WOULD_BLOCK

	APULIS_IQI_ERROR_REQUEST_NEW
	APULIS_IQI_ERROR_REQUEST_DO
	APULIS_IQI_ERROR_RESPONSE_IO

	// json
	APULIS_IQI_ERROR_JSON_UNMARSHAL
	APULIS_IQI_ERROR_JSON_MARSHAL
	APULIS_IQI_ERROR_URL_PARSE

	APULIS_IQI_WOULD_BLOCK
	APULIS_IQI_NO_AUTH
	APULIS_IQI_REMOTE_NETWORK_ERROR
	APULIS_IQI_REMOTE_REST_ERROR
	APULIS_IQI_GROUP_NO_ERROR
	APULIS_IQI_ERROR_DIR_MAKE
	APULIS_IQI_ERROR_PARSE_INT
	APULIS_IQI_ERROR_SYSTEM_NAME
	APULIS_IQI_ERROR_TASK_TYPE_EMPTY
	APULIS_IQI_ERROR_OS_RENAME_FILE
	APULIS_IQI_ERROR_PRESET_UPDATE_TYPE
	APULIS_IQI_ERROR_PERMISSION_DENIED
	APULIS_IQI_ERROR_MODELS_EXITS
	APULIS_IQI_ERROR_READ_FILE
	APULIS_IQI_ERROR_PARSE_YAML
	APULIS_IQI_ERROR_PARSE_JSON
	APULIS_IQI_ERROR_SDK_EXISTS
	APULIS_IQI_ERROR_WORKSTATION
	APULIS_IQI_ERROR_WORKSTATION_NAME_EXIST
	APULIS_IQI_ERROR_WORKSTATION_NAME_EMPTY
	APULIS_IQI_ERROR_WORKSTATION_MAX_LEN
	APULIS_IQI_SDKNAME_ERROR
	APULIS_IQI_ERROR_GETWORKSTATION
	APULIS_IQI_ERROR_WORKSTATION_DELETE
	APULIS_IQI_ERROR_RELATION
	APULIS_IQI_ERROR_CREATEPRODUCT
	APULIS_IQI_ERROR_GETPRODUCT
	APULIS_IQI_ERROR_DELETEPRODUCT
	APULIS_IQI_ERROR_PRODUCT_RELATE_INFER
	APULIS_IQI_ERROR_PRODUCT_NAME_EXIST
	APULIS_IQI_ERROR_PRODUCT_NAME_EMPTY
	APULIS_IQI_ERROR_PRODUCT_NAME_MAX_LEN
	APULIS_IQI_ERROR_WORKSTATION_USERD
	APULIS_IQI_ERROR_DELETERELATION
	APULIS_IQI_CHECKPARAMS_ERROR
	APULIS_IQI_ERROR_BOARD_PRODUCTNAME_EMPTY
	APULIS_IQI_BOARD_CREATE_ERROR
	APULIS_IQI_BOARD_GET_ERROR
	APULIS_IQI_BOARD_DELETE_ERROR
	APULIS_IQI_ERROR_PRODUCT_RELATE_DATASET
	APULIS_IQI_ERROR_PRODUCT_RELATIONS
)
const (
	APULIS_IQI_DB_ERROR = APULIS_IQI_MODULE_ID*100000 + 300 + iota
	APULIS_IQI_DB_QUERY_FAILED
	APULIS_IQI_DB_EXEC_FAILED
	APULIS_IQI_DB_DUPLICATE
	APULIS_IQI_DB_UPDATE_UNEXPECT
	APULIS_IQI_DB_WRONG_TYPE
	APULIS_IQI_DB_READ_ROWS
	APULIS_IQI_DB_DELETE_FAILED
)
const (
	APULIS_IQI_PROJECT_ERROR                     = APULIS_IQI_MODULE_ID*100000 + 400
	APULIS_IQI_PROJECT_NOT_EXIST                 = APULIS_IQI_MODULE_ID*100000 + 401
	APULIS_IQI_PROJECT_EXIST                     = APULIS_IQI_MODULE_ID*100000 + 402
	APULIS_IQI_PROJECT_MODEL_MATCH_FAILED        = APULIS_IQI_MODULE_ID*100000 + 403
	APULIS_IQI_PROJECT_INFER_CHECK_FAILED        = APULIS_IQI_MODULE_ID*100000 + 404
	APULIS_IQI_PROJECT_USED_BY_INFERS            = APULIS_IQI_MODULE_ID*100000 + 405
	APULIS_IQI_PROJECT_LAB_NOT_FOUND             = APULIS_IQI_MODULE_ID*100000 + 406
	APULIS_IQI_PROJECT_SDK_NOT_FOUND             = APULIS_IQI_MODULE_ID*100000 + 407
	APULIS_IQI_PROJECT_SDK_MODEL_TITLE_DUPLICATE = APULIS_IQI_MODULE_ID*100000 + 408
	APULIS_IQI_PROJECT_STATUS_ERROR              = APULIS_IQI_MODULE_ID*100000 + 409
	APULIS_IQI_PROJECT_MODEL_LENS_ERROR          = APULIS_IQI_MODULE_ID*100000 + 410
	APULIS_IQI_PROJECT_STOP_JOB_ERROR            = APULIS_IQI_MODULE_ID*100000 + 411
	APULIS_IQI_PROJECT_MODEL_MIN                 = APULIS_IQI_MODULE_ID*100000 + 412
	APULIS_IQI_PROJECT_BINDING_DATA_CONN         = APULIS_IQI_MODULE_ID*100000 + 413

	APULIS_IQI_RECHECK_FAILED                      = APULIS_IQI_MODULE_ID*100000 + 450
	APULIS_IQI_ANALYSIS_FAILED                     = APULIS_IQI_MODULE_ID*100000 + 451
	APULIS_IQI_PREDICT_FAILED                      = APULIS_IQI_MODULE_ID*100000 + 452
	APULIS_IQI_PREDICT_MUST_RUN                    = APULIS_IQI_MODULE_ID*100000 + 453
	APULIS_IQI_PREDICT_RUNING                      = APULIS_IQI_MODULE_ID*100000 + 454
	APULIS_IQI_PREDICT_NEED_DATASET                = APULIS_IQI_MODULE_ID*100000 + 455
	APULIS_IQI_PREDICT_NEED_FILE                   = APULIS_IQI_MODULE_ID*100000 + 456
	APULIS_IQI_PREDICT_NEED_INFER_URL              = APULIS_IQI_MODULE_ID*100000 + 457
	APULIS_IQI_PREDICT_TASK_DATASET_CREATE_FAILED  = APULIS_IQI_MODULE_ID*100000 + 458
	APULIS_IQI_PREDICT_TASK_DATASET_PUBLISH_FAILED = APULIS_IQI_MODULE_ID*100000 + 459
	APULIS_IQI_PREDICT_TASK_SUBMIT_FIND_NO_RECHECK = APULIS_IQI_MODULE_ID*100000 + 460
	APULIS_IQI_PREDICT_TASK_SUBMIT_MQ_SEND_RECHECK = APULIS_IQI_MODULE_ID*100000 + 461
	APULIS_IQI_RECKECK_ANNOT_NOTFOUNT              = APULIS_IQI_MODULE_ID*100000 + 462
	APULIS_IQI_PREDICT_TASK_IMAGES_NOT_FOUND       = APULIS_IQI_MODULE_ID*100000 + 463
)
const (
	APULIS_IQI_SDK_ERROR        = APULIS_IQI_MODULE_ID*100000 + 500
	APULIS_IQI_SDK_NOT_EXIST    = APULIS_IQI_MODULE_ID*100000 + 501
	APULIS_IQI_SDK_REF_FAILED   = APULIS_IQI_MODULE_ID*100000 + 502
	APULIS_IQI_SDK_UNREF_FAILED = APULIS_IQI_MODULE_ID*100000 + 503
)

const (
	APULIS_IQI_ERROR_AUTO_ANNOTATION_INFER_CONF_NOT_FOUND                              = APULIS_IQI_MODULE_ID*100000 + 600
	APULIS_IQI_ERROR_AUTO_ANNOTATION_GET_AVAIL_NPU_COUNT                               = APULIS_IQI_MODULE_ID*100000 + 601
	APULIS_IQI_ERROR_AUTO_ANNOTATION_NOT_ENOUGH_NPU                                    = APULIS_IQI_MODULE_ID*100000 + 602
	APULIS_IQI_ERROR_AUTO_ANNOTATION_ALREADY_RUNNING_CANNOT_RUN                        = APULIS_IQI_MODULE_ID*100000 + 603
	APULIS_IQI_ERROR_AUTO_ANNOTATION_REQUEST_ADMAGIC_BACKEND_BIND_IMAGE_SUBTASK        = APULIS_IQI_MODULE_ID*100000 + 604
	APULIS_IQI_ERROR_AUTO_ANNOTATION_CREATE_INFERENCE_TASK_FAIL                        = APULIS_IQI_MODULE_ID*100000 + 605
	APULIS_IQI_ERROR_AUTO_ANNOTATION_JOB_DETAIL_NOT_FOUND                              = APULIS_IQI_MODULE_ID*100000 + 606
	APULIS_IQI_ERROR_AUTO_ANNOTATION_STOP_ERR_INFER_TASK_HAS_NOT_BEEN_CREATED_PLS_WAIT = APULIS_IQI_MODULE_ID*100000 + 607
	APULIS_IQI_ERROR_AUTO_ANNOTATION_STOP_ERR_INFER_TASK_IS_STOPPING_PLS_WAIT          = APULIS_IQI_MODULE_ID*100000 + 608
	APULIS_IQI_ERROR_AUTO_ANNOTATION_STOP_ERR_REQUEST_ADMAGIC_BACKEND_STOP_JOB         = APULIS_IQI_MODULE_ID*100000 + 609
)

const (
	APULIS_IQI_ERROR_AOM = APULIS_IQI_MODULE_ID*100000 + 700 + iota
	APULIS_IQI_ERROR_AOM_QUOTA_NOT_FOUND
	APULIS_IQI_ERROR_AOM_MEMORY_USED_EXCEED
	APULIS_IQI_ERROR_AOM_QUOTA_DEVICE_EXCEED
	APULIS_IQI_ERROR_AOM_QUOTA_CPU_EXCEED
	APULIS_IQI_ERROR_AOM_QUOTA_CPU_EXCEED_NOT_FOUND
	APULIS_IQI_ERROR_AOM_QUOTA_CPU_EXCEED_GROUP
	APULIS_IQI_ERROR_JOB_PRECHECK_QUOTA_ERROR
	APULIS_IQI_ERROR_AOM_PRECHECK_NEED_QUEUE
)
const (
	APULIS_IQI_ERROR_DATASET            = APULIS_IQI_MODULE_ID*100000 + 800
	APULIS_IQI_ERROR_DATASET_PUBLISHED  = APULIS_IQI_MODULE_ID*100000 + 801
	APULIS_IQI_ERROR_DATASET_PUBLISHING = APULIS_IQI_MODULE_ID*100000 + 802
)
const (
	APULIS_IQI_ERROR_INFER_GET_LAB                     = APULIS_IQI_MODULE_ID*100000 + 901
	APULIS_IQI_ERROR_INFER_DB_ERR                      = APULIS_IQI_MODULE_ID*100000 + 902
	APULIS_IQI_ERROR_INFER_PROJECT_EXIST               = APULIS_IQI_MODULE_ID*100000 + 903
	APULIS_IQI_ERROR_INFER_PRODUCT_SERIALNUMBER_EXIST  = APULIS_IQI_MODULE_ID*100000 + 904
	APULIS_IQI_ERROR_INFER_GEN_INFER_REQ               = APULIS_IQI_MODULE_ID*100000 + 905
	APULIS_IQI_ERROR_INFER_MARSHL_QUATO                = APULIS_IQI_MODULE_ID*100000 + 906
	APULIS_IQI_ERROR_INFER_BIND_CHANNEL                = APULIS_IQI_MODULE_ID*100000 + 907
	APULIS_IQI_ERROR_INFER_MARSHL_DC                   = APULIS_IQI_MODULE_ID*100000 + 908
	APULIS_IQI_ERROR_INFER_CREATE_PIPLINE              = APULIS_IQI_MODULE_ID*100000 + 909
	APULIS_IQI_ERROR_INFER_CREATE_VERSION              = APULIS_IQI_MODULE_ID*100000 + 910
	APULIS_IQI_ERROR_INFER_CREATE_INFER                = APULIS_IQI_MODULE_ID*100000 + 911
	APULIS_IQI_ERROR_INFER_UPDATE                      = APULIS_IQI_MODULE_ID*100000 + 912
	APULIS_IQI_ERROR_INFER_GET_VERSION_LIST            = APULIS_IQI_MODULE_ID*100000 + 913
	APULIS_IQI_ERROR_INFER_GET_LIST                    = APULIS_IQI_MODULE_ID*100000 + 914
	APULIS_IQI_ERROR_INFER_GEN_OUTPUT                  = APULIS_IQI_MODULE_ID*100000 + 915
	APULIS_IQI_ERROR_INFER_GET_DETAIL                  = APULIS_IQI_MODULE_ID*100000 + 916
	APULIS_IQI_ERROR_INFER_DATA_PARSE                  = APULIS_IQI_MODULE_ID*100000 + 917
	APULIS_IQI_ERROR_INFER_OP_FAILED                   = APULIS_IQI_MODULE_ID*100000 + 918
	APULIS_IQI_ERROR_INFER_DELETE_FAILED               = APULIS_IQI_MODULE_ID*100000 + 919
	APULIS_IQI_ERROR_INFER_UPDATE_FLOW                 = APULIS_IQI_MODULE_ID*100000 + 920
	APULIS_IQI_ERROR_INFER_PROJECT_NOT_EXIST           = APULIS_IQI_MODULE_ID*100000 + 921
	APULIS_IQI_ERROR_INFER_NAME_EXIST                  = APULIS_IQI_MODULE_ID*100000 + 922
	APULIS_IQI_ERROR_INFER_PROJECT_REPEAT              = APULIS_IQI_MODULE_ID*100000 + 923
	APULIS_IQI_ERROR_INFER_PRODUCT_SERIALNUMBER_REPEAT = APULIS_IQI_MODULE_ID*100000 + 924
	APULIS_IQI_ERROR_INFER_START_MONITOR               = APULIS_IQI_MODULE_ID*100000 + 925
	APULIS_IQI_ERROR_INFER_GET_CHANNEL                 = APULIS_IQI_MODULE_ID*100000 + 926
	APULIS_IQI_ERROR_INFER_TEMPLATE_NOT_FOUND          = APULIS_IQI_MODULE_ID*100000 + 927
	APULIS_IQI_ERROR_INFER_COORDINATE_NOT_FOUND        = APULIS_IQI_MODULE_ID*100000 + 928
)

const (
	APULIS_IQI_ERROR_MLOPS_MODEL_UNSUPPORT  = APULIS_IQI_MODULE_ID*100000 + 1000
	APULIS_IQI_ERROR_MLOPS_JSON_CONVERT     = APULIS_IQI_MODULE_ID*100000 + 1001
	APULIS_IQI_ERROR_MLOPS_SDK_FETCH_FAILED = APULIS_IQI_MODULE_ID*100000 + 1002
)
const (
	APULIS_IQI_ERROR_KEYMAP       = APULIS_IQI_MODULE_ID*100000 + 1100
	APULIS_IQI_ERROR_KEYMAP_EMPTY = APULIS_IQI_MODULE_ID*100000 + 1101
)

const (
	APULIS_IQI_ERROR_CANNOT_SUBMIT                     = APULIS_IQI_MODULE_ID*100000 + 1200
	APULIS_IQI_ERROR_PRODUCT_TEMPLATE_NAME_EXIST       = APULIS_IQI_MODULE_ID*100000 + 1201
	APULIS_IQI_ERROR_PRODUCT_TEMPLATE_ZIP_NAME_INVALID = APULIS_IQI_MODULE_ID*100000 + 1202
)

type APIError interface {
	Error() string
	Errno() int
}

func (e *APIException) Error() string {
	return e.Msg
}
func (e *APIException) Errno() int {
	return e.Code
}

type APIException struct {
	StatusCode int         `json:"-"` // http status code ,should be rarely used
	Code       int         `json:"code"`
	Data       interface{} `json:"data"`
	Msg        string      `json:"msg"`
}

func NewAPIException(statusCode, code int, msg string) *APIException {
	return &APIException{
		StatusCode: statusCode,
		Code:       code,
		Msg:        msg,
	}
}
func NewAPIExceptionWithData(statusCode, code int, msg string, data interface{}) *APIException {
	return &APIException{
		StatusCode: statusCode,
		Code:       code,
		Msg:        msg,
		Data:       data,
	}
}

func NotFoundError() *APIException {
	return NewAPIException(http.StatusBadRequest, APULIS_IQI_NOT_FOUND, ErrMsg(APULIS_IQI_NOT_FOUND))
}

func ParameterError(msg string) *APIException {
	return NewAPIExceptionWithData(http.StatusBadRequest, APULIS_IQI_PARAM_ERROR, ErrMsg(APULIS_IQI_PARAM_ERROR, msg), map[string]string{"V": msg})
}

func NotImplementError() *APIException {
	return NewAPIException(http.StatusBadRequest, APULIS_IQI_NOT_IMPLEMENT, ErrMsg(APULIS_IQI_NOT_IMPLEMENT))
}

func RaiseReqWouldBlock(msg string) *APIException {
	return NewAPIException(http.StatusOK, APULIS_IQI_WOULD_BLOCK, msg)
}

func RaiseHttpError(code int, status string) APIError {
	return NewAPIExceptionWithData(http.StatusBadRequest, code, status, map[string]interface{}{
		"V": status,
	})
}
func RaiseSuccess() APIError {
	return NewAPIException(http.StatusOK, SUCCESS, ErrMsg(SUCCESS))
}
func RaiseAPIError(code int, args ...string) APIError {
	if len(args) > 0 {
		return NewAPIException(http.StatusBadRequest, code, args[0])
	}

	return NewAPIException(http.StatusBadRequest, code, "")
}

func RaiseServerError(code int, args ...string) APIError {
	if len(args) > 0 {
		return NewAPIException(http.StatusBadRequest, code, args[0])
	}
	return NewAPIException(http.StatusBadRequest, code, "")
}

func InternalServerError() APIError {
	return NewAPIException(http.StatusInternalServerError, APULIS_IQI_DB_ERROR, "Internal Server error")
}

func WrapperError(err error) APIError {
	if err == nil {
		return nil
	}
	if h, ok := err.(*APIException); ok {
		return h
	}
	return NewAPIException(http.StatusInternalServerError, APULIS_IQI_DB_ERROR, err.Error())
}
func RaiseAPIErrorFromRest(restResp *CommResponse) APIError {
	return &APIException{
		StatusCode: http.StatusBadRequest,
		Code:       restResp.Code,
		Data:       restResp.Data,
		Msg:        restResp.Msg,
	}
}

func RaiseAPIErrorAuto(code int, args ...string) APIError {
	if len(args) == 0 {
		return NewAPIException(http.StatusBadRequest, code, ErrMsg(code))
	}
	return NewAPIExceptionWithData(http.StatusBadRequest, code, ErrMsg(code, args[0]), map[string]interface{}{
		"V": args[0],
	})
}

func RaiseAPIErrorWouldBlock(code int, args ...interface{}) APIError {
	return NewAPIException(http.StatusOK, code, ErrMsg(code, args...))
}

func CheckWithError(err error, code int) APIError {
	if err != nil {
		return RaiseAPIError(code, err.Error())
	} else if code != 0 {
		return RaiseAPIError(code)
	} else {
		return nil
	}
}
func RaiseProxy(httpCode int, data interface{}) APIError {
	return &APIException{
		StatusCode: httpCode,
		Data:       data,
	}
}
